/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2016-2018, LomboTech Co.Ltd.
 * Author: lomboswer <lomboswer@lombotech.com>
 *
 * memctrl_dev.h - memctrl device head file
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#ifndef __MEMCTRL_DEV_H
#define __MEMCTRL_DEV_H

#include <linux/fs.h>

#define MAX_SUB_MASTER	10

struct data_unit {
	const char *name;	/* data unit name */
	u32 size;		/* B or KB or MB */
};

struct data_unit_array {
	const struct data_unit *data_units;	/* handle of data_units */
	u32 array_size;				/* data_units size */
};

struct cfg_unit {
	const char *name;
	u32 cfg;		/* the value write to reg */
	u32 size;		/* value for display unit:ms */
	u32 div;		/* transform size unit to @unit */
	const char *unit;	/* ms or s */
};

struct flaw_unit_array {
	const struct cfg_unit *flaw_units;
	u32 array_size;
};

struct sample_unit_array {
	const struct cfg_unit *sample_units;
	u32 array_size;
};

struct channel_info {
	const char *name;
	u32 hwnum;	/* master number in spec */
};

struct channel_info_array {
	const struct channel_info *master_channels;
	u32 array_size;
};

/**
 * master priority
 */
struct master_priority {
	int level0;	/* port priority */
	int level1;	/* the priority of masetr in sarb */
	u32 qos_val;	/* qos priotiry */
};

struct master_pos {
	u32 level0;	/* port pos */
	u32 level1;	/* master pos */
};

/**
 *@ reg_offset: register offset: priority or sarb qos
 *@ bit_offset: priority_sub or qos_sr_sub bit offset
 *@ bit_mask: bit mask = ((1 << bitwidth) -1) << bit_offset
 *@ rd_reg_offset: every sub RQOS reg_offset
 *@ rd_bit_offset: every master RQOS reg_offset
 */
struct master_location {
	int reg_offset;
	int bit_offset;
	int bit_mask;
	int rd_reg_offset;
	int rd_bit_offset;
};

/**
 *@ priority_root: prot describe
 *@ priority_sub: description of masetr in sarb
 *@ qos_sr_root: sarb_sr root describe
 *@ qos_sr_sub: sarb_sr master describe
 *@ name: master name
 *@ master_num: master num
 */
struct master_info {
	struct master_location priority_root;
	struct master_location priority_sub[MAX_SUB_MASTER];
	struct master_location qos_sr_root;
	struct master_location qos_sr_sub[MAX_SUB_MASTER];
	char *name[MAX_SUB_MASTER];
	int master_num;
};

struct master_prio_array {
	const struct master_info *master_prio;
	u32 array_size;
};

enum memctrl_bw_bits {
	BW_TIMEWINDOW = 0,
	BW_DATASIZE,
	BW_RANDOMMODE,
	BW_CTRLMODE,
	BW_RANDOMSEED
};

struct bw_bits_name {
	const char *name;
	const char *ref;
	u32 val;
};

struct bw_bits_name_array {
	const struct bw_bits_name *names;
	u32 array_size;
};

#if defined(CONFIG_ARCH_LOMBO_N7V1)
enum memctrl_bwctrl_id {
	/* start NOC */
	BWCTRL_AX = 0,
	/* start SARB */
	BWCTRL_VC = 0,
	BWCTRL_VDC,
};
#elif defined(CONFIG_ARCH_LOMBO_N7V3)
enum memctrl_bwctrl_id {
	/* start NOC */
	BWCTRL_AX0 = 0,
	BWCTRL_HVC,
	/* start SARB */
	BWCTRL_MPEG = 0,
	BWCTRL_VGSS,
	BWCTRL_IVX,
};
#elif defined(CONFIG_ARCH_LOMBO_N7V5) || defined(CONFIG_ARCH_LOMBO_N5V1) \
	|| defined(CONFIG_ARCH_LOMBO_N7V7)
enum memctrl_bwctrl_id {
	/* start NOC */
	BWCTRL_AX0 = 0,
#ifdef CONFIG_ARCH_LOMBO_N7V7
	BWCTRL_HVX,
#endif
	/* start SARB */
	BWCTRL_MJEPG = 0,
	BWCTRL_VGSS,
	BWCTRL_IVX,
};
#elif defined(CONFIG_ARCH_LOMBO_N9V1)
enum memctrl_bwctrl_id {
	/* start NOC */
	BWCTRL_AX0 = 0,
	BWCTRL_AX1,
	BWCTRL_GPU,
	/* start SARB */
	BWCTRL_VC = 0,
	BWCTRL_VGSS,
	BWCTRL_IVX,
	BWCTRL_VDC,
	BWCTRL_HVC,
	BWCTRL_USB3_0,
	BWCTRL_USB3_1,
};
#elif defined(CONFIG_ARCH_LOMBO_N9V3)
enum memctrl_bwctrl_id {
	/* start NOC */
	BWCTRL_AX = 0,
	BWCTRL_HVC,
	/* start SARB */
	BWCTRL_VC = 0,
	BWCTRL_VGSS,
	BWCTRL_IVX,
	BWCTRL_USB3_0,
	BWCTRL_PCIE0,
	BWCTRL_PCIE1,
	BWCTRL_SATA,
};
#endif

enum memctrl_bwctrl_arb {
	NOC = 0,
	SARB,
};

/**
 * bwctrl_master_info - list decribe the master of bwctrl
 *
 * @name: the master name, for display and match string from user
 * @hwnum: mater sort in NOC SPEC
 */
struct bwctrl_master_info {
	const char *name;
	u32 hwnum;
	u32 arbiter;
};

struct bwctrl_masters_array {
	const struct bwctrl_master_info *bwctrl_masters;
	u32 array_size;
};

const struct data_unit_array *mctrl_dev_get_data_units(void);
const struct flaw_unit_array *mctrl_dev_get_flaw_units(void);
const struct sample_unit_array *mctrl_dev_get_sample_units(void);
const struct channel_info_array *mctrl_dev_get_master_channels(void);
const struct master_prio_array *mctrl_dev_get_memtrl_master_prio(void);
const struct bw_bits_name_array *mctrl_dev_get_bwctrl_bits(void);
const struct bwctrl_masters_array *mctrl_dev_get_bwctrl_masters(void);

#endif
